﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using Algorithms.Tools;

/*
 * TH07 Groep 10
 * ----------------------------------------------------------------------------------
 * Versie   Door        Commentaar
 * 0.1      Mike        Opzet en programmeer werk
 * 0.2      Luca        Optimalisatie code
 *                      Hernoemen variabelen en functies
 *                      overbodige code verwijderd 
 *                      crop image naar eigen tool classe verplaatst.
 * 
 *               
 */

namespace THO7AlgoritmTimerApplication
{
    class CharacterTrainer
    {

        #region private variables
        /// <summary>
        /// Segments to search 5(5*5) 25 segements
        /// </summary>
        private readonly int VECTORSIZE = 5;
        /// <summary>
        /// Static list of trainedCharacters
        /// Static so the trained characters wont be reset!
        /// </summary>
        private static List<TrainedCharacter> trainedCharacters;
        private static Boolean trained = false;
        private VisionImage testImage;
        #endregion

        #region public getters and setters
        public VisionImage TestImage
        {
            get { return testImage; }
            set { testImage = value; }
        }
        #endregion

        #region constructors
        /// <summary>
        /// Constructor
        /// </summary>
        public CharacterTrainer()
        {
            if (trainedCharacters == null) trainedCharacters = new List<TrainedCharacter>();
        }
        #endregion

        #region public functions
        /// <summary>
        /// Train on the given font file
        /// </summary>
        /// <param name="fontFile">fontFile to train</param>
        /// <param name="stringToTrain">characters to train on</param>
        public void TrainFromFont(string fontFile, string stringToTrain)
        {

            PrivateFontCollection fonts = new PrivateFontCollection();
            fonts.AddFontFile(fontFile);
            char[] charsToTrain = Encoding.ASCII.GetChars(Encoding.ASCII.GetBytes(stringToTrain));

            FontFamily family = (FontFamily)fonts.Families.GetValue(0);

            foreach (char ch in charsToTrain)
            {
                Bitmap objBmp = new Bitmap(1, 1);
                int Width = 0;
                int Height = 0;

                // Create the Font object for the image text drawing.    
                Font objFont = new Font(family, 200, System.Drawing.FontStyle.Bold);

                // Create a graphics object to measure the text's width and height.
                Graphics objGraphics = Graphics.FromImage(objBmp);

                // This is where the bitmap size is determined.
                Width = (int)objGraphics.MeasureString("" + ch, objFont).Width;
                Height = (int)objGraphics.MeasureString("" + ch, objFont).Height;

                // Create the bmpImage again with the correct size for the text and font.
                objBmp = new Bitmap(objBmp, new Size(Width, Height));

                // Add the colors to the new bitmap.
                objGraphics = Graphics.FromImage(objBmp);

                // Set Background color
                objGraphics.Clear(Color.White);
                objGraphics.SmoothingMode = SmoothingMode.None;
                objGraphics.DrawString("" + ch, objFont, new SolidBrush(Color.FromArgb(0, 0, 0)), 0, 0);
                objGraphics.Flush();

                
                Crop cropper = new Crop();
                VisionImage cropped = new VisionImage(cropper.run(new VisionImage(objBmp)));

                TrainCharacterFromImage(ch, cropped);
            }
        }

       

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fontFiles"></param>
        public void TrainFromFonts(string[] fontFiles)
        {
            if (!trained)
            {
                foreach (string fontFile in fontFiles)
                {
                    TrainFromFont(fontFile, "ABCDEFGHIJKLMNOPQRSTVWXYZ"); //toetsenbord volgorde
                }
                trained = true;
            }
        }

        /// <summary>
        /// Train the program with one character
        /// </summary>
        /// <param name="Character">character to train</param>
        /// <param name="img">image to train</param>
        public void TrainCharacterFromImage(char Character, VisionImage img)
        {
            Character character = new Character();
            character.CalculateFromImage(img);
            trainedCharacters.Add(new TrainedCharacter(Character, character.Properties));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public char GetCharacterFromCharacter(Character character)
        {

            TrainedCharacter final = null;
            int lowestDifference = -1;
            foreach (TrainedCharacter tc in trainedCharacters)
            {
                int difference = tc.Match(character);
                if (lowestDifference == -1)
                {
                    lowestDifference = difference;
                    final = tc;
                }
                else if (difference < lowestDifference)
                {
                    lowestDifference = difference;
                    final = tc;
                }
            }

            return final.Character;
        }

        #endregion
    }
}
